﻿package Leophy.controls 
{
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import Leophy.controls.MotionClip.EasyMotionMovieClip;
	import Leophy.controls.MotionClip.MontionFuns;
	import Leophy.Interfaces.IControls.IScroll.IScorllEnable;
	import Leophy.Interfaces.IControls.IScroll.IScrollUI;
	import Leophy.LeophyVersion;
	
	/**
	 * ...
	 * @author TOPHY
	 */
	dynamic public class MyDisplayObjectContainer extends EasyMotionMovieClip implements IScorllEnable
	{
		/////===================================================  静态变量　
		public static var M_RESIZE:String = "onResize";
		public static var M_SCROLL_RG_CHANGED:String = "onScrollRectangleChanged";
		
		/////===================================================  变量　
		private var _reSizeAble:Boolean = true;
		private var _canDrag:Boolean = true;
		private var _showResizeHandly:Boolean = true;
		
		protected var _broadLineThin:uint = 0;
		private var _backGroundColor:uint = 0x0;
		private var _backGroundAlpha:Number = 0.5;
		private var _lineColor:uint = 0x0;
		private var _lineAlpha:Number = 1;
		
		protected var _orgWidth:Number = 0;
		protected var _orgHeight:Number = 0;
		
		
		protected var _maxScrollH:Number = 0;
		protected var _maxScrollV:Number = 0;
		protected var _valueH:Number = 0;
		protected var _valueV:Number = 0;
		private var _itemXOffset:Number=0;
		private var _itemYOffset:Number = 0;
		
		private var _easeMove:Boolean = true;
		
		
		private var _mouseTop:Number=0;
		private var _mouseLeft:Number=0;
		private var _mouseRight:Number=0;
		private var _mouseBottom:Number = 0;
		
		private var _mouseDownPoint:Point;
		private var _activeBord:Number = 6;
		
		private var _container:EasyMotionMovieClip;
		private var _mask:Sprite;
		/////===================================================  属性
		/**
		 * 背景色
		 */
		public function get BackGroundColor():uint {
			return this._backGroundColor;
		}
		public function set BackGroundColor(value:uint):void {
			this._backGroundColor = value;
			drawBJ(_orgWidth,_orgHeight);
		}
		
		/**
		 * 背景透明度
		 */
		public function get BackGroundAlpha():Number {
			return this._backGroundAlpha;
		}
		public function set BackGroundAlpha(value:Number):void {
			this._backGroundAlpha = value;
			drawBJ(_orgWidth,_orgHeight);
		}
		
		/**
		 * 背景边框色
		 */
		public function get LineColor():uint {
			return this._lineColor;
		}
		public function set LineColor(value:uint):void {
			this._lineColor = value;
			drawBJ(_orgWidth,_orgHeight);
		}
		
		/**
		 * 背景边框透明度
		 */
		public function get LineAlpha():Number {
			return this._lineAlpha;
		}
		public function set LineAlpha(value:Number):void {
			this._lineAlpha = value;
			drawBJ(_orgWidth,_orgHeight);
		}
		/**
		 * X方向的偏移量
		 */
		public function get XOffset():Number {
			return _itemXOffset;
		}
		public function set XOffset(value:Number):void {
			_itemXOffset = value;
			UpdataScrolls();
		}
		/**
		 * Y方向的偏移量
		 */
		public function get YOffset():Number {
			return _itemYOffset;
		}
		public function set YOffset(value:Number) {
			_itemYOffset = value;
			UpdataScrolls();
		}
		/**
		 * 是(true)否(false)以缓动方式滚动
		 */
		public function get EasyMove():Boolean {
			return _easeMove;
		}
		public function set EasyMove(value:Boolean) {
			_easeMove = value;
		}
		
		/**
		 * 显示区域大小[只读]
		 */
		protected function get ShowRectangle ():Rectangle {
			return new Rectangle(0, 0, _mask.width, _mask.height);
		}
		/**
		 * 控制边框与边界距离
		 */
		protected function get BordSize():Number {
			return _activeBord;
		}
		protected function set BordSize(value:Number):void {
			if(_activeBord!=value){
				_activeBord = value;
				if (_showResizeHandly && _reSizeAble) {
					drawBJ(_orgWidth, _orgHeight);
					drawMsk();
				}
			}
		}
		/**
		 * [内部使用]容器
		 */
		protected function get Container():EasyMotionMovieClip {
			return this._container;
		}
		/**
		 * 是(true)否(false)可以resize
		 */
		public function get ResizeAble():Boolean {
			return _reSizeAble;
		}
		public function set ResizeAble(able:Boolean):void {
			if (this._reSizeAble != able) {
				this._reSizeAble = able;
				drawBJ(_orgWidth, _orgHeight);
				drawMsk();
			}
		}
		/**
		 * 是(true)否(false)显示Resize边框
		 */
		public function get ShowResizeHandly():Boolean {
			return _showResizeHandly;
		}
		public function set ShowResizeHandly(value:Boolean):void {
			if (this._showResizeHandly != value) {
				this._showResizeHandly = value;
				drawBJ(_orgWidth, _orgHeight);
				drawMsk();
			}
		}
		/**
		 * 是(true)否(false)可以拖拽
		 */
		public function get CanDrag():Boolean {
			return _canDrag;
		}
		public function set CanDrag(able:Boolean):void {
			if (this._canDrag != able) {
				this._canDrag = able;
				if (!this._canDrag) {
					this._mouseUpFun(null);
					this.resizeSTOP(null);
				}
			}
		}
		

		/* ＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝ INTERFACE Leophy.Interfaces.IControls.IScroll.IScorllEnable ＝＝＝＝＝＝＝＝＝＝＝＝*/
		/**
		 * [内部使用]　注册resize事件
		 * @param	sui
		 */
		public function RegistResizeEvent(sui:IScrollUI):void
		{
			this.addEventListener(M_SCROLL_RG_CHANGED, sui.onScrollSizeChanged);
		}
		/**
		 * [内部使用]　注销resize事件
		 * @param	sui
		 */
		public function UNRegistResizeEvent(sui:IScrollUI):void
		{
			this.removeEventListener(M_SCROLL_RG_CHANGED, sui.onScrollSizeChanged);
		}
		
		/**
		 * H方向滚动最小值
		 */
		public function get MinScrollH():Number
		{
			return 0;
		}
		
		/**
		 * V方向滚动最小值
		 */
		public function get MinScrollV():Number
		{
			return 0;
		}
		
		/**
		 * H方向滚动值
		 */
		public function get HValue():Number
		{
			return -this._valueH;
		}
		public function set HValue(value:Number):void
		{
			_valueH = -value;
			fixShowItemHolderPosition();
		}
		/**
		 * V方向滚动值
		 */
		public function get VValue():Number
		{
			return -this._valueV;
		}
		public function set VValue(value:Number):void
		{
			_valueV = -value;
			fixShowItemHolderPosition();
		}
		/**
		 * H方向滚动最大值
		 */
		public function get MaxScrollH():Number
		{
			return _maxScrollH;
		}
		/**
		 * V方向滚动最大值
		 */
		public function get MaxScrollV():Number
		{
			return _maxScrollV;
		}
		
		
		
		/////===================================================  函数
		public function MyDisplayObjectContainer()
		{
			LeophyVersion.version();
			configUI();
			configMouseEvent();
		}
		private function configMouseEvent() {
			this.addEventListener(MouseEvent.MOUSE_MOVE, _mouseMoveFun);
			this.addEventListener(MouseEvent.MOUSE_DOWN, _mouseDownFun);
			this.addEventListener(MouseEvent.MOUSE_UP, _mouseUpFun);
		}
		////////---------------------------------- for scroll
		/**
		 * to set max vscroll value
		 */
		protected function setMaxVScrollValue() {
			_maxScrollV = _container.height - this._mask.height;
		}
		/**
		 * to set max hscroll value;
		 */
		protected function setMaxHScrollValue() {
			_maxScrollH = _container.width - this._mask.width;
		}
		private function fixShowItemHolderPosition() {
			if (_easeMove) {
				if(this._container.hasEventListener(Event.ENTER_FRAME)){
					this._container.removeEventListener(Event.ENTER_FRAME, HolderMovefun);
				}
				this._container.addEventListener(Event.ENTER_FRAME,HolderMovefun);
			}else {
				this._container.x = _itemXOffset + _valueH;
				this._container.y = _itemYOffset + _valueV;
			}
		}
		private function HolderMovefun(ev:Event) {
			var xl:Number = _itemXOffset + _valueH - _container.x;
			var yl:Number = _itemYOffset + _valueV - _container.y;
			
			if (Math.abs(xl) > 1 || Math.abs(yl) > 1) {
				_container.x += xl / 5;
				_container.y += yl / 5;
			}else {
				_container.x = int(_itemXOffset + _valueH);
				_container.y = int(_itemYOffset + _valueV);
				_container.removeEventListener(Event.ENTER_FRAME, HolderMovefun);
			}
		}
		/**
		 * 更新滚动状态
		 * @param	ev
		 */
		public function UpdataScrolls(ev:Event=null) {
			setMaxHScrollValue();
			setMaxVScrollValue();
			this.dispatchEvent(new Event(M_SCROLL_RG_CHANGED));
		}
		////////-----------------------------------  鼠标事件
		private function _mouseMoveFun(ev:MouseEvent) {
			if (ev.currentTarget == this) {
				setMousePosition();
			}
		}
		private function setMousePosition() {
			_mouseTop = Math.max(this.mouseY, -1);
			_mouseLeft = Math.max(this.mouseX, -1);
			_mouseRight = Math.max(this._orgWidth - this.mouseX, -1);
			_mouseBottom = Math.max(this._orgHeight - this.mouseY, -1); 
		}
		private function _mouseUpFun(ev:MouseEvent) {
			if (ev == null) return;
			if (ev.currentTarget == this) {
				this.stopDrag();
			}
		}
		private function _mouseDownFun(ev:MouseEvent) {
			_mouseDownPoint = new Point(this.mouseX, this.mouseY);
			setMousePosition();
			if (ev.currentTarget == this) {
				//resize
				var rsRight:Boolean = false;
				var rsBottom:Boolean = false;
				if (_mouseRight < _activeBord && _mouseRight > 0) {
					rsRight = true;
				}
				if (_mouseBottom < _activeBord && _mouseBottom > 0) {
					rsBottom = true;
				}
				
				if (_reSizeAble && (rsRight||rsBottom)) {
					AddResizeEventToStage( rsRight, rsBottom);
				}
				else if(_canDrag){
					this.startDrag(false);
				}
				
			}
		}
		private function AddResizeEventToStage(rsRight:Boolean = false, rsBottom:Boolean = false) {
			removeResizeEventFromStage();
			if (rsRight&&!rsBottom) {
				stage.addEventListener(MouseEvent.MOUSE_MOVE, resizerightf);
			}
			else if (rsBottom&&!rsRight) {
				stage.addEventListener(MouseEvent.MOUSE_MOVE, resizebottomf);
			}
			else if (rsBottom && rsRight) {
				stage.addEventListener(MouseEvent.MOUSE_MOVE, resizeRBf);
			}
			stage.addEventListener(MouseEvent.MOUSE_UP,resizeSTOP);
		}
		private function removeResizeEventFromStage() {
			if(stage!=null){
				stage.removeEventListener(MouseEvent.MOUSE_MOVE, resizebottomf);
				stage.removeEventListener(MouseEvent.MOUSE_MOVE, resizerightf);
				stage.removeEventListener(MouseEvent.MOUSE_MOVE, resizeRBf);
				stage.removeEventListener(MouseEvent.MOUSE_MOVE, resizeSTOP);
			}
		}
		private function resizeSTOP(ev:MouseEvent) {
			removeResizeEventFromStage();
			resizeDispase();
		}
		private function resizebottomf(ev:MouseEvent) {
			if(this.mouseY>1.5*_activeBord){
				var yl:Number = this.mouseY - _mouseDownPoint.y;
				_mouseDownPoint.y = this.mouseY;
				this._orgHeight += yl;
				resizeDispase();
			}
		}
		private function resizeRBf(ev:MouseEvent) {
			var rs:Boolean = false;
			if(this.mouseX>1.5*_activeBord){
				var xl:Number = this.mouseX - _mouseDownPoint.x;
				_mouseDownPoint.x = this.mouseX;
				this._orgWidth += xl;
				rs = true;
			}
			if(this.mouseY>1.5*_activeBord){
				var yl:Number = this.mouseY - _mouseDownPoint.y;
				_mouseDownPoint.y = this.mouseY;
				rs = true;
				this._orgHeight += yl;
			}
			if(rs){
				resizeDispase();
			}
		}
		private function resizerightf(ev:MouseEvent) {
			if(this.mouseX>1.5*_activeBord){
				var xl:Number = this.mouseX - _mouseDownPoint.x;
				_mouseDownPoint.x = this.mouseX;
				this._orgWidth += xl;
				resizeDispase();
			}
		}
		private function resizeDispase() {
			this.drawBJ(this._orgWidth, this._orgHeight);
			drawMsk();
			UpdataScrolls();
			this.dispatchEvent(new Event(M_RESIZE));
		}
		///////-----------------------------------  背景
		
		/**
		 * resize 函数
		 * @param	w 宽度 
		 * @param	h 高度
		 */
		public function ResizeTo(w:uint=5,h:uint=5) {
			_orgWidth = w;
			_orgHeight = h;
			resizeDispase();
		}
		private function configUI() {
			_orgWidth = this.width;
			_orgHeight = this.height;
			for (var i = 0; i < this.numChildren; i++) {
				var db:DisplayObject = this.getChildAt(i) as DisplayObject;
				db.visible = false;
				db.width = db.height = 0;
			}
			this.scaleX = this.scaleY = 1;
			_container = new EasyMotionMovieClip();
			_mask = new Sprite ();
			
			this.addChild(_container);
			this.addChild(_mask);
			_container.mask = _mask;
			
			drawBJ(_orgWidth, _orgHeight);
			drawMsk();
		}
		private function drawMsk() {
			this._mask.graphics.clear();
			this._mask.graphics.beginFill(0, 1);
			if(_reSizeAble){
				this._mask.graphics.drawRect(Math.max(.5,_broadLineThin), Math.max(.5,_broadLineThin), _orgWidth - ((_broadLineThin*2 ) + _activeBord*4/5), _orgHeight - ((_broadLineThin*2 ) + _activeBord*4/5));
			}else {
				this._mask.graphics.drawRect(Math.max(.5,_broadLineThin), Math.max(.5,_broadLineThin), _orgWidth - ((_broadLineThin*2==0)? 1:_broadLineThin*2 ), _orgHeight - ((_broadLineThin*2==0)? 1:_broadLineThin*2 ));
			}
			this._mask.graphics.endFill();
		}
		private function drawBJ(w:Number, h:Number) {
			this.graphics.clear();
			this.graphics.lineStyle(0, _lineColor, _lineAlpha);
			this.graphics.beginFill(_backGroundColor, _backGroundAlpha);
			this.graphics.drawRect(0, 0, w, h);
			this.graphics.endFill();
			if(_reSizeAble && _showResizeHandly){
				this.graphics.lineStyle(0, _lineColor, _lineAlpha);
				this.graphics.moveTo(w - _activeBord*0.5, 0);
				this.graphics.lineTo(w - _activeBord*0.5, h - _activeBord);
				this.graphics.lineTo(w - _activeBord, h - _activeBord*0.5);
				this.graphics.lineTo(0, h - _activeBord*0.5);
			}
		}
	}
	
}